package com.heima.controller;


import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.heima.common.PageResponse;
import com.heima.entity.TbNode;
import com.heima.entity.TbOrder;
import com.heima.entity.TbOrderCollect;
import com.heima.entity.TbRegion;
import com.heima.mapper.TbOrderCollectMapper;
import com.heima.pojo.vo.AmountCollect;
import com.heima.pojo.vo.AmountCollectVo;
import com.heima.pojo.vo.TopVo;
import com.heima.service.ITbNodeService;
import com.heima.service.ITbOrderCollectService;
import com.heima.service.ITbOrderService;
import com.heima.service.ITbRegionService;
import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;

import java.util.stream.Collectors;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author author
 * @since 2024-06-09
 */
@RestController
@Slf4j
@RequestMapping("/api/order-service")
public class TbOrderController {

    @Autowired
    private ITbOrderService iTbOrderService;

    @Autowired
    private ITbOrderCollectService iTbOrderCollectService;

    @Autowired
    private TbOrderCollectMapper tbOrderCollectMapper;

    @Autowired
    private ITbNodeService iTbNodeService;

    @Autowired
    private ITbRegionService iTbRegionService;

    @GetMapping("/order/search")
    public PageResponse<TbOrder> selectOrder(@RequestParam(value = "pageIndex",required = false) Integer pageIndex,
                                             @RequestParam(value = "pageSize",required = false) Integer pageSize,
                                             @RequestParam(value = "orderNo",required = false) String orderNo,
                                             @RequestParam(value = "startDate",required = false)
                                                 @DateTimeFormat(pattern = "yyyy-MM-dd HH:ss:mm") Date startDate,
                                             @RequestParam(value = "endDate",required = false)
                                                 @DateTimeFormat(pattern = "yyyy-MM-dd HH:ss:mm") Date endDate){
        Page<TbOrder> page = new Page<>(pageIndex,pageSize);
        //构建查询参数
        log.info("开始时间,结束时间,{},{}",startDate,endDate);
        LocalDateTime start = LocalDateTimeUtil.of(startDate);
        LocalDateTime end = LocalDateTimeUtil.of(endDate);
        LambdaQueryWrapper<TbOrder> wrapper = new LambdaQueryWrapper<TbOrder>()
                .like(orderNo != null, TbOrder::getOrderNo, orderNo)
                .ge(startDate != null, TbOrder::getCreateTime, start)
                .le(endDate != null, TbOrder::getCreateTime, end);

        //执行分页查询
        iTbOrderService.page(page,wrapper);

        //封装并返回结果
        PageResponse<TbOrder> response = new PageResponse<>();
        response.setPageIndex(pageIndex);
        response.setPageSize(pageSize);
        response.setTotalCount((int) page.getTotal());
        response.setCurrentPageRecords(page.getRecords());

        return response;
    }

    @GetMapping("report/orderCount")
    public String monthAmount(@RequestParam(value = "start", required = false)
                                   @DateTimeFormat(pattern = "yyyy-MM-dd") Date start,
                               @RequestParam(value = "end", required = false)
                                   @DateTimeFormat(pattern = "yyyy-MM-dd") Date end) {
        LocalDateTime s = LocalDateTimeUtil.of(start);
        LocalDate startTime = s.toLocalDate();
        LocalDateTime e = LocalDateTimeUtil.of(end);
        LocalDate endTime = e.toLocalDate();
        log.info("开始时间,结束时间,{},{}",startTime,endTime);
        List<TbOrderCollect> tbOrderCollects = tbOrderCollectMapper.selectDate(startTime,endTime);
        // 使用reduce方法计算总和
        Integer totalCount = tbOrderCollects.stream()
                .map(o -> o.getOrderCount())
                .reduce(0, Integer::sum);
        return totalCount.toString();

    }
    @GetMapping("/report/orderAmount")
    public Long saleAmount(@RequestParam(value = "start", required = false)
                                  @DateTimeFormat(pattern = "yyyy-MM-dd") Date start,
                              @RequestParam(value = "end", required = false)
                                  @DateTimeFormat(pattern = "yyyy-MM-dd") Date end){
        LocalDateTime s = LocalDateTimeUtil.of(start);
        LocalDate startTime = s.toLocalDate();
        LocalDateTime e = LocalDateTimeUtil.of(end);
        LocalDate endTime = e.toLocalDate();
        log.info("开始时间,结束时间,{},{}",startTime,endTime);
        List<TbOrderCollect> orderCollectList = iTbOrderCollectService.lambdaQuery()
                .ge(start != null, TbOrderCollect::getDate, startTime)
                .le(end != null, TbOrderCollect::getDate, endTime)
                .list();
        Long reduce = orderCollectList.stream().map(TbOrderCollect::getOrderTotalMoney)
                .reduce(0L, Long::sum);
        return reduce;
    }
    //&#x6DFB;&#x52A0;&#x6CE8;&#x91CA;
    @GetMapping("/report/skuTop/{topValue}/{start}/{end}")
    public Object getTopValue(@PathVariable("topValue") Integer topValue,
                              @PathVariable("start")  @DateTimeFormat(pattern = "yyyy-MM-dd") Date start,
                              @PathVariable("end") @DateTimeFormat(pattern = "yyyy-MM-dd") Date end){
        LocalDate startTime = LocalDateTimeUtil.of(start).toLocalDate();
        LocalDate endTime = LocalDateTimeUtil.of(end).toLocalDate();
        log.info("开始时间,结束时间,{},{}",startTime,endTime);
        List<TbOrder> tbOrderList = iTbOrderService.lambdaQuery()
                .ge(start != null, TbOrder::getCreateTime, startTime)
                .le(end != null, TbOrder::getCreateTime, endTime)
                .orderByDesc(TbOrder::getAmount)
                .list();
        List<TbOrder> tbOrders = tbOrderList.subList(0, Math.min(tbOrderList.size(), 10));

        List<TopVo> topVoList = tbOrders.stream().map(o -> {
            TopVo topVo = new TopVo();
            topVo.setSkuName(o.getSkuName());
            topVo.setCount(o.getAmount());
            return topVo;
        }).collect(Collectors.toList());
        return topVoList;
    }
    @GetMapping("/report/regionCollect/{start}/{end}")
    public AmountCollect regionCollect(
                                       @PathVariable("start") @DateTimeFormat(pattern = "yyyy-MM-dd") Date start,
                                       @PathVariable("end") @DateTimeFormat(pattern = "yyyy-MM-dd") Date end){
        LocalDate startTime = LocalDateTimeUtil.of(start).toLocalDate();
        LocalDate endTime = LocalDateTimeUtil.of(end).toLocalDate();
        List<AmountCollectVo> vo = tbOrderCollectMapper.select(startTime,endTime);

        AmountCollect amountCollect = new AmountCollect();
        List<String> xAxis = new ArrayList<>();
        List<Integer> series = new ArrayList<>();
        if (!ObjUtil.isEmpty(vo)) {
            for (AmountCollectVo collectVo : vo) {
                xAxis.add(collectVo.getXAxis());
                String[] strings = xAxis.toArray(new String[0]);
                amountCollect.setXAxis(strings);

                series.add(collectVo.getSeries());
                Integer[] integers = series.toArray(new Integer[0]);
                amountCollect.setSeries(integers);
            }
        }

        return amountCollect;
    }

    @GetMapping("/report/amountCollect/{collectType}/{start}/{end}")
    public AmountCollect amountCollect(@PathVariable("collectType") Integer collectType,
                                                 @PathVariable("start")
                                                     @DateTimeFormat(pattern = "yyyy-MM-dd") Date start,
                                                 @PathVariable("end")
                                                    @DateTimeFormat(pattern = "yyyy-MM-dd") Date end) {
        LocalDate startTime = LocalDateTimeUtil.of(start).toLocalDate();
        LocalDate endTime = LocalDateTimeUtil.of(end).toLocalDate();
        List<TbOrderCollect> tbOrderCollects = iTbOrderCollectService.lambdaQuery()
                .ge(start != null, TbOrderCollect::getDate, startTime)
                .le(end != null, TbOrderCollect::getDate, endTime)
                .orderByAsc(TbOrderCollect::getDate)
                .list();
        AmountCollect amountCollect = new AmountCollect();
        List<String> xAxis = new ArrayList<>();
        List<Integer> series = new ArrayList<>();
        for (TbOrderCollect tc : tbOrderCollects) {
            if (!ObjUtil.isEmpty(tc)) {
                xAxis.add(String.valueOf(tc.getDate()));
                series.add(tc.getNodeAmount());
            }
        }
        amountCollect.setXAxis(xAxis.toArray(new String[0]));
        amountCollect.setSeries(series.toArray(new Integer[0]));
        return amountCollect;
    }
}
